﻿// See https://aka.ms/new-console-template for more information
//策略模式
//策略模式用于算法的自由切换与扩展，他是使用较为广泛的设计模式之一。基本上凡是涉及到父类和父类之间的交互都会或多或少的涉及到这个模式。策略模式提供了一种对象仔面对多项选择时的解决方案。
//在软件开发中，我们常常会遇到一种情况，实现一个功能需要用到多种算法或者途径，一种常用的方式是通过我们硬编码来将所有算法集中到一个类中，在该类中通过多个方法，每一种方法对应一个具体的算法；当然也可以将这些算法封装在一个统一的方法中，并使用分支语句来判断选择。这两种的方法都被称之为硬编码，如果增加一种新的算法时我们就需要修改我们写好的代码，非常不利于维护和扩展。
//此时我们可以选择使用策略模式来定义一些独立的类来封装不同的算法，每一个类封装一种具体的算法，在这里，每个封装算法的类都可以是一种策略，为了保证这些策略在使用时具有一致性，一般会提供一个抽象的策略类来做算法的声明，而每种算法则对应一个具体策略类
//策略模式包含以下三个对象：
//·Context（上下文类）：上下文类是使用算法的角色，他在解决某个问题时可以采用多种策略。在上下文类中维持一个对抽象策略类的引用，用于定义所采用的策略。
//·Strategy（抽象策略类）：抽象策略类微所支持的算法声明了抽象方法，是所有策略类的父类，它可以是抽象类或具体类，也可以是接口。
//·ConcreteStrategy（具体策略类）：具体抽象类实现了在抽象策略类中声明的算法，在运行时，具体策略类对象将覆盖在上下文类中定义的抽象策略类对象，使用一种具体的算法来实现某个业务的功能

using System.Diagnostics;

List<int> list = new List<int>() { 11, 22, 33, 44, 55, 332, 11, 2, 2, 3, 4, 1123 };
SortContext context = new SortContext(new QuickSortStrategy());
//SortContext context = new SortContext(new BubbleSortStrategy());
Stopwatch Stopwatchstopwatch = Stopwatch.StartNew();
context.Sort(list);
Stopwatchstopwatch.Stop();
list.ForEach(x => Console.WriteLine(x));
Console.WriteLine("排序耗时:"+Stopwatchstopwatch.Elapsed);




Console.WriteLine("Hello, World!");

//排序算法，可以用冒泡排序，可以用快速排序
//策略接口，定义了排序的行为
internal interface ISortStrategy
{
    void Sort(List<int> list);
}

//冒泡排序策略类，实现了ISortStrategy接口
internal class BubbleSortStrategy : ISortStrategy
{
    public void Sort(List<int> list)
    {
        for (var i = 0; i < list.Count; i++)
        {
            for (var j = i; j < list.Count; j++)
            {
                if (list[i] < list[j])
                {
                    var obj = list[i];
                    list[i] = list[j];
                    list[j] = obj;
                }
            }
        }
    }
}

//快速排序策略类，实现了ISortStrategy接口
internal class QuickSortStrategy : ISortStrategy
{
    public void Sort(List<int> list)
    {
        QuickSort(list, 0, list.Count - 1);
    }

    private void QuickSort(List<int> arr, int left, int right)
    {
        if (left < right)
        {
            int i = left, j = right, pivot = arr[left];
            while (i < j)
            {
                while (i < j && arr[j] >= pivot)
                    j--;
                if (i < j)
                    arr[i++] = arr[j];
                while (i < j && arr[i] < pivot)
                    i++;
                if (i < j)
                    arr[j--] = arr[i];
            }
            arr[i] = pivot;
            QuickSort(arr, left, i - 1);
            QuickSort(arr, i + 1, right);
        }
    }
}

//排序上下文，负责持有策略对象并调用策略的方法
class SortContext
{
    private ISortStrategy _strategy;

    public SortContext(ISortStrategy strategy)
    {
        _strategy = strategy;
    }

    public void SetStrategy(ISortStrategy sortStrategy)
    {
        _strategy = sortStrategy;
    }

    public void Sort(List<int> list)
    {
        _strategy.Sort(list);
    }
}